package com.mini.grpc.server;

import com.mini.grpc.common.MethodDescriptor;

/**
 * 服务端方法定义
 * 包含方法描述符和对应的处理器
 * 
 * @param <ReqT> 请求类型
 * @param <RespT> 响应类型
 * @author Mini-gRPC
 */
public final class ServerMethodDefinition<ReqT, RespT> {
    
    private final MethodDescriptor<ReqT, RespT> method;
    private final ServerCallHandler<ReqT, RespT> handler;
    
    /**
     * 私有构造函数
     * 
     * @param method 方法描述符
     * @param handler 方法处理器
     */
    private ServerMethodDefinition(MethodDescriptor<ReqT, RespT> method, ServerCallHandler<ReqT, RespT> handler) {
        this.method = method;
        this.handler = handler;
    }
    
    /**
     * 获取方法描述符
     * 
     * @return 方法描述符
     */
    public MethodDescriptor<ReqT, RespT> getMethodDescriptor() {
        return method;
    }
    
    /**
     * 获取方法处理器
     * 
     * @return 方法处理器
     */
    public ServerCallHandler<ReqT, RespT> getServerCallHandler() {
        return handler;
    }
    
    /**
     * 创建方法定义
     * 
     * @param method 方法描述符
     * @param handler 方法处理器
     * @param <ReqT> 请求类型
     * @param <RespT> 响应类型
     * @return 方法定义实例
     */
    public static <ReqT, RespT> ServerMethodDefinition<ReqT, RespT> create(
            MethodDescriptor<ReqT, RespT> method,
            ServerCallHandler<ReqT, RespT> handler) {
        if (method == null) {
            throw new IllegalArgumentException("method cannot be null");
        }
        if (handler == null) {
            throw new IllegalArgumentException("handler cannot be null");
        }
        return new ServerMethodDefinition<>(method, handler);
    }
    
    /**
     * 使用新的处理器创建方法定义
     * 
     * @param handler 新的方法处理器
     * @return 新的方法定义实例
     */
    public ServerMethodDefinition<ReqT, RespT> withServerCallHandler(ServerCallHandler<ReqT, RespT> handler) {
        return create(method, handler);
    }
    
    @Override
    public String toString() {
        return "ServerMethodDefinition{" +
                "method=" + method.getFullMethodName() +
                ", handler=" + handler.getClass().getSimpleName() +
                '}';
    }
} 